﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using DomainDriver.DomainModeling.DataProviders;
using DomainDriver.DomainModeling.DomainObjects;

namespace DomainDriver.DomainModeling.Queries
{
    public interface IQuery<T>
    {
        bool Supports_UnCompiled_QueryPredicate { get; }
        Expression<Func<T, bool>> GetQueryPredicate_UnCompiled(IDataProvider dataProvider);
        Func<T, bool> GetQueryPredicate(IDataProvider dataProvider);
    }

    public static class IQueryUtils
    {
        public static void Assert_DoesSupport_UnCompiled_QueryPredicate<T>(this IQuery<T> query)
        {
            if (!query.Supports_UnCompiled_QueryPredicate)
            { throw new InvalidOperationException("The specified Query does not support un-compiled query predicate usage."); }
        }

        public static void Assert_DoesNotSupport_UnCompiled_QueryPredicate<T>(this IQuery<T> query)
        {
            if (query.Supports_UnCompiled_QueryPredicate)
            { throw new InvalidOperationException("The specified Query does support un-compiled query predicate usage."); }
        }

        public static Expression<Func<T, bool>> Convert_CompiledPredicate_IntoExpression<T>(this IQuery<T> query, IDataProvider dataProvider)
        {
            Func<T, bool> predicate = query.GetQueryPredicate(dataProvider);
            return Convert_CompiledPredicate_IntoExpression(predicate);
        }

        public static Expression<Func<T, bool>> Convert_CompiledPredicate_IntoExpression<T>(this Func<T, bool> predicate)
        {
            Expression<Func<T, bool>> predicateAsExpression = ((T obj) => predicate(obj));
            return predicateAsExpression;
        }
    }
}